Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

201
Views
{NodeJS} "Cannot set headers after they are sent to the client NodeJS"

What I did wrong here? I receive "Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client NodeJS", can somebody help me?

I am using:

Express mongoose (for MongoDB)

Controller

export const postResetPasswordEmail: Controller = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
   const { email } = req.body
   try {
      const errors: IValidatorError = getValidationErrors(req)
      if (Object.keys(errors).length !== 0) {
         res.status(403).json({ errors })
         return
      }
      const user = await User.findOne({ email })
      if (!user) {
         res.status(404).json({ message: AuthenticationErrors.noEmailFound })
         return
      } else {
         if (!(user.passwordUpdatedAt === undefined || (new Date(user.passwordUpdatedAt) < new Date()))) {
            res.status(404).json({ message: AuthenticationErrors.error10MinutesPassword })
            return
         }
      }
      const token = generateJWT({ email }, JWTKEY, '10m')
      await sendResetPasswordMail(email, token, next)
      res.status(200)
         .json({ message: SuccessMessages.resetPassword })
   } catch (err: any) {
      catchError(err, next)
   }
}

sendResetPasswordMail

const sendResetPasswordMail: SendResetPasswordMail = async (userEmail: string, token: string, next: NextFunction): Promise<void> => {
   try {
      const transporter = nodemailer.createTransport({
         service: 'gmail',
         auth: {
            user: adminEmail.email,
            pass: adminEmail.pass
         }
      })
      const mailOptions = {
         from: adminEmail.email,
         to: userEmail,
         subject: 'Reset password',
         text: `Reset password: http://localhost:3000/resetPassword?token=${token}`
      }
      await transporter.sendMail(mailOptions)
   } catch (err: any) {
      catchError(err, next)
   }
}

generateJWT

const generateJWT: GenerateJWT = (userInfo: IUserInfo, JWTKEY: string, expireTime: string): string =>
   jwt.sign({ ...userInfo }, JWTKEY, { expiresIn: expireTime })
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I see a flaw in sendResetPasswordMail: Suppose you have an exception there and it calls catchError within sendResetPasswordMail catch block, in this case it will indirectly call next, which in turn would call res.status().send() within default express error handler.

Nevertheless, despite the exception sendResetPasswordMail will return control to you controller which would try to send status 200 after that, and if by that time the error handler's already sent the response you will get the error.

The valid behaviour would be not to catch exceptions within sendResetPasswordMail and leave it to the caller. And you also can remove next parameter from sendResetPasswordMail

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!